﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using YiYiTong.Rocket.Entity;
using YiYiTong.Rocket.Helper;

namespace YiYiTong.Rocket.ManageWeb
{
    public class AuthorizeFilterAttribute : ActionFilterAttribute
    {
        //统一权限验证入口
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (filterContext == null)
            {
                throw new ArgumentNullException("filterContext");
            }
            var path = filterContext.HttpContext.Request.Path.ToLower();
            //1.忽略对登录页,验证码页,错误提示页的权限判定
            if (path.Equals("/") || path.Equals("/user") || path.Equals("/user/login") || path.Equals("/user/captchaimage") || path.Equals("/user/checkvalidatecode") || path.Equals("/home/error") || path.Equals("/home/Default") || path.Equals("/user/captchatext"))
                return;


            //2.验证页面是否登陆,获取当前用户信息
            var user = new CurrentUser();
            //用户未登录,或登录超时
            if (!user.isLogin)
            {
                filterContext.Result = new ContentResult { Content = GetJSMsg("抱歉，登录已失效，请重新登录！", true) };
                return;
            }

            //3.忽略无需权限判定的请求
            object[] attrsNoVer = filterContext.ActionDescriptor.GetCustomAttributes(typeof(NoVerifyAttribute), true);
            if (attrsNoVer.Length == 1)
                return;

            //4.权限判定开始
            object[] attrs = filterContext.ActionDescriptor.GetCustomAttributes(typeof(ViewPageAttribute), true);
            //当前Action请求是否为具体的功能页
            var isViewPage = attrs.Length == 1;
            //暂时先不做权限判断
            AuthorizeCore(filterContext, isViewPage, user.user.uid.ToString(), user.user.loginName);
        }

        //权限判断业务逻辑
        protected virtual void AuthorizeCore(ActionExecutingContext filterContext, bool isViewPage, string uid, string loginName)
        {
            var controllerName = filterContext.RouteData.Values["controller"].ToString().ToLower();
            var actionName = filterContext.RouteData.Values["action"].ToString().ToLower();
            string url = "/" + controllerName + "/" + actionName;

            //5.判断用户是否拥有菜单权限
            if (isViewPage)
            {
                //获取用户菜单
                List<MenuInfo> menulist = DataCacheHelper.Get<List<MenuInfo>>(uid);
                if (menulist == null || menulist.Count == 0)
                {
                    //没有查到用户所拥有的页面菜单
                    filterContext.Result = new ContentResult { Content = GetJSMsg("抱歉，你不具有当前页面的访问权限", false) };
                    return;
                }

                var menus = from n in menulist where n.menuUrl.ToLower() == url select n;
                bool isExits = false;
                foreach (var i in menus)
                {
                    isExits = true;
                    break;
                }

                //用户不存在菜单权限
                if (!isExits)
                {
                    filterContext.Result = new ContentResult { Content = GetJSMsg("抱歉，你不具有当前页面的访问权限", false) };
                    return;
                }
            }
            else
            {
                //6.判断用户是否拥有action操作权限
                List<ActionInfo> actionlist = DataCacheHelper.Get<List<ActionInfo>>(uid + loginName);

                //加入日志 pengshsh 20161018 add
                //NetLogHelper.WriteTextLog(uid + loginName + "---action操作权限", JsonHelper.Serialize(actionlist), DateTime.Now);

                //zhangry 2017-05-11 集合为null缓存失效
                if (actionlist == null)
                {
                    filterContext.Result = new ContentResult { Content = GetJSMsg("抱歉，登录已失效，请重新登录！", true) };
                    return;
                }
                else if (actionlist.Count == 0)
                {
                    //没有查到用户所拥有的action功能
                    filterContext.Result = new ContentResult { Content = GetJSMsg("抱歉，你不具有当前操作的权限", false) };
                    return;
                }

                var actions = from n in actionlist where n.actionName.ToLower() == actionName && n.controllerName.ToLower() == controllerName select n;
                bool isExits = false;
                foreach (var i in actions)
                {
                    isExits = true;
                    break;
                }

                //用户不存在action操作权限
                if (!isExits)
                {
                    filterContext.Result = new ContentResult { Content = GetJSMsg("抱歉，你不具有当前操作的权限", false) };
                    return;
                }

                //记录操作日志
                string strOp = string.Format("审计操作-用户【name:{0};uid:{1}】于{2}执行{3}/{4}，请求数据：{5}", loginName, uid, DateTime.Now, controllerName, actionName, JsonHelper.Serialize(filterContext.ActionParameters));
                LogHelper.Info(strOp);
            }
        }

        //返回自定义js isJump 是否返回到登录页面
        private string GetJSMsg(string message, bool isJump)
        {
            StringBuilder strJs = new StringBuilder();
            strJs.Append("<!DOCTYPE html>");
            strJs.Append("<html xmlns=\"http://www.w3.org/1999/xhtml\">");
            strJs.Append("<head>");
            strJs.Append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />");
            strJs.Append("<title></title>");
            strJs.Append("<link href=\"/Css/assets/css/bui-min.css\" rel=\"stylesheet\" />");
            strJs.Append("<link href=\"/Css/assets/css/dpl-min.css\" rel=\"stylesheet\" />");
            strJs.Append("<script src=\"/Css/assets/js/jquery-1.8.1.min.js\"></script>");
            strJs.Append("<script src=\"/Css/assets/js/bui-min.js\"></script>");
            strJs.Append("<script src=\"/Css/assets/js/message/sea.js\"></script>");
            strJs.Append("<script src=\"/Css/assets/js/message/config.js\"></script>");
            strJs.Append("</head>");
            strJs.Append("<body>");
            strJs.Append("</body>");
            strJs.Append("</html>");
            strJs.Append("<script>");
            strJs.Append("BUI.use('bui/overlay', function (overlay) {");
            strJs.Append("$(function () {");
            strJs.Append(" BUI.Message.Alert('" + message + "', function () {");
            if (!isJump)
                strJs.Append("history.go(-1);");
            else
                strJs.Append("window.parent.location.href = '/user/loginOut'");
            strJs.Append("  }, 'warning');");
            strJs.Append("  });");
            strJs.Append(" });");
            strJs.Append("</script>");
            return strJs.ToString();
        }
    }
}